﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SurfaceAd.Assistant;
using SurfaceAd.Common;
using SurfaceAd.Entities;
using SurfaceAd.Entities.Ad;
using SurfaceAd.Views;
using Windows.Graphics.Display;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media;

/**
 * 创建时间：2014/9/19 10:23:41
 * 作者：yong.blackcore
 * Email：itblackhole@outlook.com
 * QQ：50404503
 * 描述：开屏或插屏广告
 */
namespace SurfaceAd
{
    public sealed partial class SurfaceAdScreen : UserControl
    {

        #region ******************************属性变量事件******************************
        //public event AdRequestErrorHandler OnAdRequestFailed;
        public event ApplicationAuthHandler OnApplicationAuthEvent;
        public event AdRequestHandler OnAdRequest;
        public event AdContentHandler OnAdClick;

        #region ********************私有变量********************
        Grid LayoutRoot;
        Popup popupLanucheAdViewContainer, popupRunningAdViewContainer;
        private Boolean IsExecuteInterstitialTicked = false;
        /// <summary>
        /// 设备信息
        /// </summary>
        private DeviceInformation deviceInfo = new DeviceInformation();
        private NetworkInfo networkInfo = new NetworkInfo();
        private GeolocatorInfo geolocatorInfo = new GeolocatorInfo();
        /// <summary>
        /// 广告刷新定时器
        /// </summary>
        private DispatcherTimer adRefreshTimer;
        /// <summary>
        /// 是否正在请求广告
        /// </summary>
        private Boolean IsAdLoading = false;
        /// <summary>
        /// 广告是否被点击
        /// </summary>
        private Boolean IsAdClicking = false;
        private WebViewPage navigatePopup;

        #endregion ********************私有变量********************

        #region ********************广告控件参数********************
        private String adToken = String.Empty;
        private String adPosition = String.Empty;
        private Int32 adRefreshInterval = Constants.AdRefreshIntervalDefault;
        private Int32 minAdRefreshInterval = Constants.AdRefreshIntervalMin;
        private Boolean isShowCloseIcon = true;
        private String adRequestUrl = Constants.AdRequestAddress;
        private AdRequestModel adRequestModel = AdRequestModel.Debug;
        private AdInterstitialScreenType interstitialScreenAdType;
        private Double interstitialScreenAdShowTime;

        /// <summary>
        /// 平台提供的AdToken
        /// </summary>
        public String AdToken
        {
            get
            {
                return this.adToken;
            }
            set
            {
                this.adToken = value;
            }
        }

        /// <summary>
        /// 平台提供的AdPosition
        /// </summary>
        public String AdPosition
        {
            get
            {
                return this.adPosition;
            }
            set
            {
                this.adPosition = value;
            }
        }

        /// <summary>
        /// 最小值不能小于5秒
        /// </summary>
        [DefaultValue(Constants.AdRefreshIntervalMin)]
        public Int32 AdRefreshInterval
        {
            get
            {
                return this.adRefreshInterval;
            }
            set
            {
                if (value <= 0)
                    value = Constants.AdRefreshIntervalDefault;
                else if (value <= minAdRefreshInterval)
                    value = minAdRefreshInterval;
                this.adRefreshInterval = value;
            }
        }

        /// <summary>
        /// 广告控件是否显示可移除标记
        /// <para>默认显示移除icon</para>
        /// </summary>
        [DefaultValue(true)]
        public Boolean IsShowCloseIcon
        {
            get { return isShowCloseIcon; }
            set { isShowCloseIcon = value; }
        }

        /// <summary>
        /// 广告位对应的数据请求地址
        /// </summary>
        [DefaultValue(Constants.AdRequestAddress)]
        public String AdRequestUrl
        {
            get
            {
                return this.adRequestUrl;
            }
            set
            {
                if (!string.IsNullOrWhiteSpace(value))
                    this.adRequestUrl = value;
            }
        }

        [DefaultValue(AdRequestModel.Debug)]
        public AdRequestModel AdModel
        {
            get { return adRequestModel; }
            set { adRequestModel = value; }
        }

        /// <summary>
        /// 开屏广告显示时长
        /// <para>单位为秒，最短为3秒</para>
        /// <para>推荐不要设置太长时间，最大为6秒</para>
        /// <para>仅在InterstitialAdType值为AdInterstitialScreenType.Screen下有效</para>
        /// </summary>
        [DefaultValue(3)]
        public double InterstitialScreenAdShowTime
        {
            get { return interstitialScreenAdShowTime; }
            set
            {
                if (value <= 3)
                    value = 3;
                else if (value >= 6)
                    value = 6;
                interstitialScreenAdShowTime = value;
            }
        }

        /// <summary>
        /// 广告类型
        /// <para>开屏或插屏两种</para>
        /// </summary>        
        public AdInterstitialScreenType InterstitialScreenAdType
        {
            get { return interstitialScreenAdType; }
            set { interstitialScreenAdType = value; }
        }
        #endregion ********************广告控件参数********************

        #region ********************开发者登录验证********************
        /// <summary>
        /// 如果登录失败，是否重新登录<br/>
        /// 默认是需要重新登录(首次)
        /// </summary>
        private bool isReLogin = true;
        private bool timerLoginRunning = false;//是否在请求中
        private Timer timerLogin;
        private AuthResponse authResponse = null;
        #endregion ********************开发者登录验证********************
        #endregion ******************************属性变量事件******************************


        #region ******************************广告控件构造函数及其初始化******************************
        public SurfaceAdScreen()
        {
            //加上try/catch主要是捕获初始化异常
            try
            {
                this.popupLanucheAdViewContainer = new Popup();
                this.popupRunningAdViewContainer = new Popup();
                this.LayoutRoot = new Grid();
                this.LayoutRoot.Children.Add(this.popupLanucheAdViewContainer);
                this.LayoutRoot.Children.Add(this.popupRunningAdViewContainer);
                this.Content = this.LayoutRoot;
                //                
                this.Loaded += SurfaceAdScreen_Loaded;
                this.Unloaded += SurfaceAdScreend_Unloaded;

                //TODO WPWRTC 错误处理Windows.Graphics.Display:GetForCurrentView must be called on a thread that is associated with a CoreWindow.
                //使用此事件，在引用此控件的界面会有以上异常信息
                //Windows.Graphics.Display.DisplayInformation.GetForCurrentView().OrientationChanged += SurfaceAdStandard_OrientationChanged;
                OrientationChangedHandler();
                Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;//这里会有异常
                //TODO WPWRTC 退出应用时停止广告请求
                //Window.Current.VisibilityChanged += rootPage_VisibilityChanged;
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), "SurfaceAdScreen");
            }
        }

        /// <summary>
        /// OrientationChanged事件
        /// <para>因为GetForCurrentView是工作的UI线程的，切换到UI线程即可</para>
        /// <para>否则会有：Windows.Graphics.Display:GetForCurrentView must be called on a thread that is associated with a CoreWindow.异常！</para>
        /// </summary>
        async void OrientationChangedHandler()
        {
            try
            {
                await (CoreWindow.GetForCurrentThread()).Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    Windows.Graphics.Display.DisplayInformation.GetForCurrentView().OrientationChanged += SurfaceAdScreend_OrientationChanged;
                });
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), "OrientationChangedHandler");
            }
        }

        void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
        {
            if (this.navigatePopup != null)
            {
                this.navigatePopup.CloseWebViewPage();
                e.Handled = true;
            }
        }

        void rootPage_VisibilityChanged(object sender, VisibilityChangedEventArgs e)
        {
            //if (e.Visible)
            //    this.SurfaceAdStandard_Loaded(null, null);
            //else
            //    this.SurfaceAdStandard_Unloaded(null, null);
        }


        void SurfaceAdScreend_OrientationChanged(Windows.Graphics.Display.DisplayInformation sender, object args)
        {
            if (this.navigatePopup != null)
            {
                this.navigatePopup.OrientationChanged();
            }
        }

        void SurfaceAdScreend_Unloaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            //释放广告请求对象
            this.IsAdLoading = false;
            this.IsAdClicking = false;
            this.isReLogin = true;
            this.timerLoginRunning = false;
            this.StopAdRefreshTimer();
        }

        void SurfaceAdScreen_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            //TODO WPWRTC:登录后是否要将登录信息保存？
            InitAdControl();
        }

        public SurfaceAdScreen(String adToken, String adPosition, Int32 adRefreshInterval, AdInterstitialScreenType adInterstitialScreenType, Double interstitialScreenAdShowTime, String adRequestUrl)
            : this()
        {
            this.AdToken = adToken;
            this.AdPosition = adPosition;
            if (adRefreshInterval <= 0)
                this.AdRefreshInterval = Constants.AdRefreshIntervalDefault;
            else if (adRefreshInterval <= minAdRefreshInterval)
                this.AdRefreshInterval = minAdRefreshInterval;
            else
                this.AdRefreshInterval = adRefreshInterval;
            this.InterstitialScreenAdType = adInterstitialScreenType;
            if (interstitialScreenAdShowTime <= 3)
                this.InterstitialScreenAdShowTime = 3;
            else if (interstitialScreenAdShowTime >= 6)
                this.InterstitialScreenAdShowTime = 6;
            else
                this.InterstitialScreenAdShowTime = interstitialScreenAdShowTime;
            this.AdRequestUrl = adRequestUrl;
        }

        /// <summary>
        /// 初始化AdControl
        /// <para>加载应用配置文件信息，权限难</para>
        /// <para>获取手机设备信息</para>
        /// <para>网络连接信息</para>
        /// <para>登录验证</para>
        /// </summary>
        /// <param name="adMode"></param>
        private async void InitAdControl()
        {
            try
            {
                //参数验证
                if (!ValidateRequest())
                {
                    return;
                }
                //功能权限验证            
                //LogHelper.LogInfo("IsInternetClientCapability" + AppxManifestHelper.IsInternetClientCapability);
                //LogHelper.LogInfo("IsInternetClientServerCapability" + AppxManifestHelper.IsInternetClientServerCapability);
                //await AppxManifestHelper.InitAsyncOperation();
                //LogHelper.LogInfo("IsInternetClientCapability" + AppxManifestHelper.IsInternetClientCapability);
                //LogHelper.LogInfo("IsInternetClientServerCapability" + AppxManifestHelper.IsInternetClientServerCapability);
                if (!await AppxManifestHelper.LoadAppxManifestAsyncOperation())
                {
                    this.ThrowAdRequestEvent(SurfaceAdStatus.Config_Error, "加载配置文件信息出错！");
                    return;
                }
                if ((!AppxManifestHelper.IsInternetClientCapability && !AppxManifestHelper.IsInternetClientServerCapability))
                {
                    if (this.OnApplicationAuthEvent != null)
                    {
                        this.OnApplicationAuthEvent(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.Network_UnConnected, Description = "未连接网络！" });
                    }
                    return;
                }
                //设备信息            
                this.deviceInfo.NavigateAppCodeName = await NavigatorHelper.GetNavigateValueByKeyAsync(WebViewNavigatorKey.appCodeName.ToString());
                this.deviceInfo.NavigateAppName = await NavigatorHelper.GetNavigateValueByKeyAsync(WebViewNavigatorKey.appName.ToString());
                this.deviceInfo.NavigateAppVersion = await NavigatorHelper.GetNavigateValueByKeyAsync(WebViewNavigatorKey.appVersion.ToString());
                this.deviceInfo.NavigateLanguage = await NavigatorHelper.GetNavigateValueByKeyAsync(WebViewNavigatorKey.language.ToString());
                this.deviceInfo.NavigatePlatform = "Win32NT";// await NavigatorHelper.GetNavigateValueByKeyAsync(WebViewNavigatorKey.platform.ToString());
                this.deviceInfo.NavigateSystemLanguage = await NavigatorHelper.GetNavigateValueByKeyAsync(WebViewNavigatorKey.systemLanguage.ToString());
                while (string.IsNullOrWhiteSpace(deviceInfo.DeviceUserAgentByWebView))
                {
                    LogHelper.LogInfo("userAgent...");//耗时0.3s,
                    await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        UserAgentHelper.GetUserAgentFromWebView(this.LayoutRoot);
                        deviceInfo.DeviceUserAgentByWebView = UserAgentHelper.UserAgent;
                    });
                    await Task.Delay(100);//延迟0.1秒，获取UserAgentFromWebView
                }
                deviceInfo.GetDeviceCustomerUserAgent();
                //LogHelper.LogInfo(this.deviceInfo.ToString(), this.GetType(), "InitAdControl");
                //网络信息
                this.networkInfo = NetworkHelper.GetDeviceNetworkInfo();
                //if (this.networkInfo != null)
                //    LogHelper.LogInfo(this.networkInfo.ToString(), this.GetType(), "InitAdControl");
                //地址位置信息
                if (AppxManifestHelper.IsLocationCapability)
                {
                    this.geolocatorInfo = await GeolocatorHelper.GetGeolocatorLocationAsyncOperation();
                    //if (this.geolocatorInfo != null)
                    //    LogHelper.LogInfo(this.geolocatorInfo.ToString(), this.GetType(), "InitAdControl");
                }
                else
                {
                    this.geolocatorInfo = new GeolocatorInfo();
                }
                //登录验证
                this.authResponse = new AuthResponse()
                {
                    AdMode = this.AdModel,
                    No = this.AdPosition,
                    U = this.AdToken
                };
                object[] loginArguments = new object[] { this.AdToken, this.AdPosition, this.deviceInfo.DeviceUniqueId, this.deviceInfo.DeviceCustomerUserAgent, this.AdModel };
                timerLogin = new Timer(TimerLoginCallback, loginArguments, 100, 1000 * 10);
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), "InitAdControl");
            }
        }

        #region ********************初始化并调度********************
        private void InitAd()
        {
            try
            {
                if (authResponse == null)
                {
                    this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_ArgumentHasError, "获取请求地址出错");
                    return;
                }
                string url = authResponse.url;
                if (string.IsNullOrWhiteSpace(url))
                {
                    this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_ArgumentHasError, "获取请求地址出错");
                    return;
                }
                else if ("404".Equals(url.Trim()))
                {
                    this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_ArgumentHasError, "请求AdToken错误");
                    return;
                }
                else if ("400".Equals(url.Trim()))
                {
                    this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_ArgumentHasError, "请求参数不完整");
                    return;
                }
                Uri uri = new Uri(url);
            }
            catch (Exception err)
            {
                this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_ArgumentHasError, "请求有误，" + err.Message);
                return;
            }
        }

        private async void StartAdRefreshTimer()
        {
            await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                try
                {
                    if (this.adRefreshTimer == null)
                    {
                        this.adRefreshTimer = new DispatcherTimer();
                        this.adRefreshTimer.Interval = new TimeSpan(0, 0, this.AdRefreshInterval);
                        this.adRefreshTimer.Tick += adRefreshTimer_Tick;
                    }
                    if (!this.IsAdClicking && !this.IsAdLoading)
                    {
                        LogHelper.LogInfo("=====================开启调度器", this.GetType(), "StartAdRefreshTimer");
                        this.adRefreshTimer.Start();
                    }
                }
                catch (Exception err)
                {
                    LogHelper.LogError("StartAdRefreshTimer:" + err.ToString(), this.GetType(), "StartAdRefreshTimer");
                }
            });
        }

        private void StopAdRefreshTimer()
        {
            if (this.adRefreshTimer != null)
            {
                LogHelper.LogInfo("=====================停止调度器", this.GetType(), "StopAdRefreshTimer");
                this.adRefreshTimer.Stop();
                this.adRefreshTimer = null;
            }
        }

        private void adRefreshTimer_Tick(object sender, object e)
        {
            this.LoadAd();
        }

        private void LoadAd()
        {
            if (IsAdLoading)
            {
                LogHelper.LogInfo("正在请求广告中......", this.GetType(), "LoadAd");
                return;
            }

            IsAdLoading = true;
            this.StopAdRefreshTimer();
            if (!NetworkHelper.IsConnectedToInternet())
            {
                this.ThrowAdRequestEvent(SurfaceAdStatus.Network_UnConnected, "无法访问网络！");
                this.IsAdLoading = false;
                this.StartAdRefreshTimer();
                return;
            }

            //请求广告
            //this.CreateAdContent();//测试
            this.InitAdContent();//
        }
        #endregion ********************初始化并调度********************
        #endregion ******************************广告控件构造函数及其初始化******************************


        #region  ******************************用户登录验证******************************
        private Boolean ValidateRequest()
        {
            Boolean flag = true;
            String description = String.Empty;
            if (String.IsNullOrWhiteSpace(this.AdToken))
            {
                description = "AdToken无效！";
                flag = false;
            }
            else if (String.IsNullOrWhiteSpace(this.AdPosition))
            {
                description = "AdPositionId无效！";
                flag = false;
            }
            else if (string.IsNullOrWhiteSpace(this.AdRequestUrl))
            {
                description = "AdRequestUrl无效！";
                flag = false;
            }
            else if (this.InterstitialScreenAdType == AdInterstitialScreenType.None)
            {
                description = "AdInterstitialScreenType无效！";
                flag = false;
            }
            else
            {
                try
                {
                    Uri uri = new Uri(this.AdRequestUrl);
                }
                catch (Exception err)
                {
                    description = "AdRequestUrl有误，" + err.Message;
                    flag = false;
                }
            }

            if (!flag)
            {
                LogHelper.LogError(description, this.GetType(), "ValidateRequest");
                if (this.OnAdRequest != null)
                {
                    OnAdRequest(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.AdRequest_ArgumentHasError, Description = description });
                }
            }
            return flag;
        }

        private void TimerLoginCallback(object loginArguments)
        {
            if (timerLoginRunning)
            {
                LogHelper.LogInfo("正在运行中......", this.GetType(), "TimerLoginCallback");
                return;
            }
            //
            timerLoginRunning = true;
            if (this.isReLogin)
            {
                object[] userInfo = loginArguments as object[];
                AuthHelper auth = new AuthHelper();
                auth.OnLoginHandler += Auth_OnLoginHandler;
                auth.Login(this.AdRequestUrl, userInfo[0].ToString(), userInfo[1].ToString(), userInfo[2].ToString(), userInfo[3].ToString(), (AdRequestModel)userInfo[4]);
            }
            else
            {
                if (this.timerLogin != null)
                    this.timerLogin.Dispose();
                this.timerLogin = null;
            }
        }

        async void Auth_OnLoginHandler(AuthResponse response)
        {
            if (string.IsNullOrWhiteSpace(response.ToString()))
            {
                isReLogin = true;
                if (this.OnApplicationAuthEvent != null)
                {
                    this.OnApplicationAuthEvent(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.Auth_LoginFailure, Description = "InitAdControl has failure,retry......" });
                }
                LogHelper.LogInfo("InitAdControl has failure,retry......", this.GetType());
            }
            else
            {
                isReLogin = false;
                authResponse.url = response.url;
                authResponse.val = response.val;
                authResponse.NetSpeed = response.NetSpeed;
                LogHelper.LogInfo(string.Format("Auth is success,url:{0},val:{1},netspeed:{2}", authResponse.url, authResponse.val, authResponse.NetSpeed), this.GetType());
                //
                if (!this.isReLogin)
                {
                    if (this.timerLogin != null)
                        this.timerLogin.Dispose();
                    this.timerLogin = null;
                    await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        //初始化
                        this.InitAd();
                        //加载广告
                        this.LoadAd();
                    });
                }
            }
            //
            this.timerLoginRunning = false;
        }
        #endregion    ******************************用户登录验证******************************


        #region ******************************事件回调信息******************************
        /// <summary>
        /// 调用OnAdRequestFailed事件
        /// </summary>
        /// <param name="errorCode"></param>
        /// <param name="description"></param>
        private async void ThrowAdRequestEvent(SurfaceAdStatus errorCode, String description)
        {
            try
            {
                await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                {
                    if (this.OnAdRequest != null)
                    {
                        this.OnAdRequest(this.LayoutRoot, new SurfaceAdEventArgs()
                        {
                            StatusCode = errorCode,
                            Description = description
                        });
                    }
                });
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), "ThrowAdRequestEvent");
            }
        }
        #endregion ******************************事件回调信息******************************


        #region ******************************广告内容******************************
        private void InitAdContent()
        {
            string requestAdQuery = this.ConcatAdRequestParameter();
            LogHelper.LogInfo(requestAdQuery, this.GetType(), "InitAdContent");
            requestAdQuery = ApiHelper.EncodeBase64(Encoding.UTF8, requestAdQuery);
            if (string.IsNullOrWhiteSpace(requestAdQuery))
            {
                this.IsAdLoading = false;
                this.StartAdRefreshTimer();
                return;
            }
            //
            try
            {
                //LogHelper.LogInfo("请求参数：" + requestAdQuery, this.GetType(), "InitAdContent");
                requestAdQuery = Uri.EscapeUriString(requestAdQuery);
                string requestAdUrl = string.Concat(this.authResponse.url, Constants.Ad_REQUESTQUERYKEY, requestAdQuery);
                LogHelper.LogInfo("请求地址：" + requestAdUrl, this.GetType(), "InitAdContent");
                //
                Uri requestAdUri = new Uri(requestAdUrl, UriKind.Absolute);
                this.CreateSurfaceAdHttpRequest(requestAdUri);
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), "InitAdContent");
                this.IsAdLoading = false;
                this.StartAdRefreshTimer();
            }
        }

        #region ********************拼接广告请求的参数********************
        private string ConcatAdRequestParameter()
        {
            StringBuilder result = new StringBuilder();
            result.Append("no=").Append(this.adToken);
            result.Append("&p=").Append(this.adPosition);
            //
            result.Append("&u=").Append(this.deviceInfo.DeviceUniqueId);
            result.Append("&ua=").Append(this.deviceInfo.DeviceCustomerUserAgent);
            result.Append("&udid=").Append(this.networkInfo.NetcardId);
            result.Append("&os=").Append(this.deviceInfo.DeviceOs);
            result.Append("&osv=").Append(this.deviceInfo.DeviceOsVersion);
            result.Append("&w=").Append(this.deviceInfo.ScreenWidth);
            result.Append("&h=").Append(this.deviceInfo.ScreenHeight);
            result.Append("&ver=").Append(Constants.AdSDKVersion);
            result.Append("&net=").Append(this.networkInfo.NetAdapterType.Id);
            result.Append("&sr=").Append(this.deviceInfo.ScreenSize);
            result.Append("&cpu=").Append(string.Empty);
            result.Append("&mem=").Append(string.Empty);
            result.Append("&lon=").Append(this.geolocatorInfo.Longitude);
            result.Append("&lat=").Append(this.geolocatorInfo.Latitude);
            result.Append("&cel=").Append(string.Empty);
            result.Append("&d=").Append(Convert.ToInt32(adRequestModel));
            result.Append("&apid=").Append(AppxManifestHelper.PhoneIdentityPhonePublisherId);
            return result.ToString();
        }
        #endregion ********************拼接广告请求的参数********************

        #region ********************向服务器请求广告数据********************
        private void CreateSurfaceAdHttpRequest(Uri requestAdUri)
        {
            HttpWebRequest request = null;
            try
            {
                LogHelper.LogInfo("开始请求广告数据", this.GetType(), "CreateSurfaceAdHttpRequest");
                if (this.OnAdRequest != null)
                {
                    this.OnAdRequest(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.AdReqeust_Begin, Description = "开始请求广告数据" });
                }
                request = HttpWebRequest.CreateHttp(requestAdUri);
                request.Method = "POST";
                request.Headers["UserAgent"] = this.deviceInfo.DeviceUserAgentByWebView;
                request.BeginGetResponse(AdRequestResponseCallback, request);
            }
            catch (Exception err)
            {
                if (request != null)
                {
                    request.Abort();
                }
                LogHelper.LogInfo(err.Message, this.GetType(), "CreateSurfaceAdHttpRequest");
                this.IsAdLoading = false;
                this.StartAdRefreshTimer();
            }
        }

        private void AdRequestResponseCallback(IAsyncResult asynchronousResult)
        {
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            StreamReader streamRead = null;
            string content = string.Empty;
            try
            {
                request = (HttpWebRequest)asynchronousResult.AsyncState;
                response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
                //获取应答码
                int statusCode = Convert.ToInt32(response.StatusCode);
                string statusText = response.StatusDescription;

                //应答头信息验证
                using (Stream streamResponse = response.GetResponseStream())
                {
                    string adJson = string.Empty;
                    //获取请求信息
                    streamRead = new StreamReader(streamResponse, Encoding.UTF8);
                    if (streamRead != null)
                    {
                        content = streamRead.ReadToEnd();
                        if (!string.IsNullOrWhiteSpace(content))
                        {
                            LogHelper.LogInfo(content, this.GetType(), "ResponseCallback");
                            string baseResult = ApiHelper.DecodeBase64(content);
                            if (!string.IsNullOrWhiteSpace(baseResult))
                            {
                                LogHelper.LogInfo(baseResult, this.GetType(), "ResponseCallback");
                                adJson = baseResult;
                            }
                        }
                    }
                    //
                    if (!string.IsNullOrWhiteSpace(adJson))
                    {
                        this.CreateAdContent(adJson);
                    }
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.Message, this.GetType(), "ResponseCallback");
                if (this.OnAdRequest != null)
                {
                    this.OnAdRequest(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.AdReqeust_Begin, Description = err.Message });
                }
            }
            finally
            {
                if (streamRead != null)
                {
                    streamRead.Dispose();
                }
                if (response != null)
                {
                    response.Dispose();
                }
                this.IsAdLoading = false;
                this.StartAdRefreshTimer();
            }
        }
        #endregion ********************向服务器请求广告数据********************

        #region ********************将广告数据填充至广告控件********************
        private void CreateAdContent(string adJsonContent)
        {
            AdJson adJson = new AdResponseHelper().ConvertToAdResponse(adJsonContent);
            if (adJson == null)
            {
                this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_Failure, "解析广告数据出错！");
                return;
            }
            if (!adJson.Validity)
            {
                this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_Failure, "解析广告数据出错！");
                return;
            }
            //
            AdResponse adResponse = adJson.AdContent;
            if (adResponse == null)
            {
                this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_Failure, adJson.Message);
                return;
            }
            //不等于200就是请求失败了
            if (!"200".Equals(adResponse.Code))
            {
                if ("404".Equals(adResponse.Code))
                {
                    this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_ArgumentHasError, string.Format("请求参数[AdToken:{0}]错误！", this.adToken));
                }
                else if ("400".Equals(adResponse.Code))
                {
                    this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_ArgumentHasError, "请求参数不完整！");
                }
                else
                {
                    this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_Failure, String.Concat("请求失败，错误码：", adResponse.Code));
                }
                return;
            }
            //可处理广告数据
            try
            {
                if (this.InterstitialScreenAdType == AdInterstitialScreenType.Interstitial)
                {
                    this.CreateAdContentToInterstitial(adResponse);
                }
                else if (this.InterstitialScreenAdType == AdInterstitialScreenType.Screen)
                {
                    this.CreateAdContentToScreen(adResponse);
                }
                else
                {
                    this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_ArgumentHasError, "AdInterstitialScreenType参数设置有误！");
                }
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), "CreateAdContent");
                this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_Failure, err.Message);
            }
        }

        #region **********开屏广告**********
        /// <summary>
        /// 开屏广告
        /// </summary>
        private async void CreateAdContentToScreen(AdResponse adResponse)
        {
            await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                if (this.popupLanucheAdViewContainer != null)
                {
                    this.popupLanucheAdViewContainer.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                    this.popupLanucheAdViewContainer.IsOpen = false;
                    this.popupLanucheAdViewContainer.Child = null;
                }
                this.popupLanucheAdViewContainer = new Popup()
                {
                    Width = Window.Current.Bounds.Width,
                    Height = Window.Current.Bounds.Height
                };
                Grid grid = new Grid()
                {
                    Background = new SolidColorBrush(Colors.Transparent),
                    HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center,
                    VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center,
                    Width = this.popupLanucheAdViewContainer.Width,
                    Height = this.popupLanucheAdViewContainer.Height
                };
                //TODO WPWRTC 只支持图片插屏广告
                if (!adResponse.AdContentType.ToString().Equals(AdType.BannerImage.ToString()))
                {
                    return;
                }
                //
                Image image = new Image() { Stretch = Stretch.Fill };
                image.Height = grid.Height;
                image.Width = grid.Width;
                StorageCachedImage sci = new StorageCachedImage(new Uri(adResponse.AdImage.ImageUrl));
                sci.OnStorageImageStatus += delegate(ImageStatus imageStatus)
                {
                    if (imageStatus == ImageStatus.Success)
                    {
                        image.Source = sci;
                        this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_Success, "广告填充完成！");
                        image.IsDoubleTapEnabled = false;
                        image.IsRightTapEnabled = false;
                        image.Tapped += delegate(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
                        {
                            //开屏广告不支持点击事件，仅展示
                        };
                        //填充广告素材
                        grid.Children.Add(image);
                        //
                        this.popupLanucheAdViewContainer.Child = grid;
                        this.popupLanucheAdViewContainer.IsOpen = true;
                        //插屏广告显示时长 
                        DispatcherTimer timer = new DispatcherTimer();
                        timer.Interval = TimeSpan.FromMilliseconds(1000 * this.InterstitialScreenAdShowTime);
                        timer.Tick += (ss, ee) =>
                        {
                            IsExecuteInterstitialTicked = true;
                            if (this.popupLanucheAdViewContainer != null)
                            {
                                this.popupLanucheAdViewContainer.IsOpen = false;
                                this.popupLanucheAdViewContainer.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                                this.popupLanucheAdViewContainer = null;
                            }
                            timer.Stop();
                            this.StopAdRefreshTimer();
                        };
                        if (!IsExecuteInterstitialTicked)
                        {
                            timer.Start();
                        }
                    }
                    else
                    {
                        if (this.popupLanucheAdViewContainer != null)
                        {
                            this.popupLanucheAdViewContainer.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                            this.popupLanucheAdViewContainer.IsOpen = false;
                            this.popupLanucheAdViewContainer.Child = null;
                        }
                        this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_Failure, "广告填充失败！");
                    }
                };

            });
        }
        #endregion **********开屏广告**********

        #region **********插屏广告**********
        /// <summary>
        /// 插屏广告
        /// </summary>
        private async void CreateAdContentToInterstitial(AdResponse adResponse)
        {
            await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                if (this.popupRunningAdViewContainer != null)
                {
                    this.popupRunningAdViewContainer.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                    this.popupRunningAdViewContainer.IsOpen = false;
                    this.popupRunningAdViewContainer.Child = null;
                }
                this.popupRunningAdViewContainer = new Popup();
                //TODO WPWRTC 只支持图片插屏广告
                if (!adResponse.AdContentType.ToString().Equals(AdType.BannerImage.ToString()))
                {
                    return;
                }

                //设置Popup在屏幕中的位置，居中
                this.popupRunningAdViewContainer.VerticalOffset = (Window.Current.Bounds.Height - adResponse.AdImage.Height) / 2.00;
                this.popupRunningAdViewContainer.HorizontalOffset = (Window.Current.Bounds.Width - adResponse.AdImage.Width) / 2.00;
                //Popup大小
                this.popupRunningAdViewContainer.Height = adResponse.AdImage.Height;
                this.popupRunningAdViewContainer.Width = adResponse.AdImage.Width;
                //
                Grid grid = new Grid()
                {
                    Background = new SolidColorBrush(Colors.Transparent),
                    HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center,
                    VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center,
                    Width = this.popupRunningAdViewContainer.Width,
                    Height = this.popupRunningAdViewContainer.Height
                };
                //
                Image image = new Image() { Stretch = Stretch.Uniform };
                //image.Height = grid.Height;
                //image.Width = grid.Width;
                StorageCachedImage sci = new StorageCachedImage(new Uri(adResponse.AdImage.ImageUrl));
                sci.OnStorageImageStatus += delegate(ImageStatus imageStatus)
                {
                    if (imageStatus == ImageStatus.Success)
                    {
                        image.Source = sci;
                        this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_Success, "广告填充完成！");
                        image.IsDoubleTapEnabled = false;
                        image.IsRightTapEnabled = false;
                        image.Tapped += delegate(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
                        {
                            this.StopAdRefreshTimer();
                            IsAdClicking = true;
                            //点击广告
                            if (this.OnAdClick != null)
                            {
                                this.OnAdClick(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.AdContent_Click, Description = "广告被点击！" });
                            }
                            ClickAdHandler(adResponse);
                        };
                        //填充广告素材及其绘制关闭广告位图标按钮
                        grid.Children.Add(image);
                        DrawAdCloseIcon(grid);
                        //
                        this.popupRunningAdViewContainer.Child = grid;
                        //
                        DisplayInformation.GetForCurrentView().OrientationChanged += delegate(DisplayInformation displayInfomationSender, object displayInfomationArgs)
                        {
                            OrientationChanged2Popup(this.popupRunningAdViewContainer, grid, adResponse.AdImage.Height, adResponse.AdImage.Width);
                        };
                        //
                        this.popupRunningAdViewContainer.IsOpen = true;
                    }
                    else
                    {
                        if (this.popupRunningAdViewContainer != null)
                        {
                            this.popupRunningAdViewContainer.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                            this.popupRunningAdViewContainer.IsOpen = false;
                            this.popupRunningAdViewContainer.Child = null;
                        }
                        this.ThrowAdRequestEvent(SurfaceAdStatus.AdRequest_Failure, "广告填充失败！");
                    }
                };
            });
        }

        /// <summary>
        /// 横竖屏切换时，插屏的Popup显示位置定位
        /// </summary>
        /// <param name="popup"></param>
        /// <param name="grid"></param>
        /// <param name="height"></param>
        /// <param name="weight"></param>
        private void OrientationChanged2Popup(Popup popup, Grid grid, double height, double weight)
        {
            if (popup != null)
            {
                OrientationScreenSize screenSize = OrientationScreenSizeHelper.GetScreenSize();
                popup.VerticalOffset = (screenSize.Height - height) / 2.00;
                popup.HorizontalOffset = (screenSize.Width - weight) / 2.00;
            }
        }
        #endregion **********插屏广告**********

        #endregion ********************将广告数据填充至广告控件********************

        #region ********************广告内容图标事件********************
        /// <summary>
        /// 广告位：绘制关闭广告位图标
        /// </summary>
        //private async Task<Boolean> DrawAdCloseIcon()
        private bool DrawAdCloseIcon(Grid grid)
        {
            if (!this.IsShowCloseIcon)
            {
                //不显示删除广告位标记
                return false;
            }
            double repeateSize = 24;
            try
            {
                //在WinRT中不支持GetManifestResourceStream方法，但在ClassLibrary中可以使用此方法读取Embedded Resource类型的资源文件。
                //var s = Assembly.Load(new AssemblyName("SurfaceAd")).GetManifestResourceStream(@"SurfaceAd.Images.EmbeddedResourceFile.xml");
                //StreamReader sr = new StreamReader(s);
                //LogHelper.LogInfo("========================"+sr.ReadToEnd());

                //1.需要将SurfaceAdImages文件夹粘贴至引用此类的项目中去
                //var uri = new System.Uri("ms-appx:///SurfaceAdImages/closead.png");
                //var storagefile = await StorageFile.GetFileFromApplicationUriAsync(uri);
                //IRandomAccessStream irandom = await storagefile.OpenAsync(FileAccessMode.Read);
                ////Stream streamClosead = irandom.GetInputStreamAt(0).AsStreamForRead();                
                //BitmapImage bimg = new BitmapImage();
                //bimg.SetSource(irandom);
                //Image image = new Image();
                //image.Source = bimg;
                //2.使用如下方法即可(需要将SurfaceAdImages文件夹粘贴至引用此类的项目中去)
                Image adCloseIcon = new Image();
                adCloseIcon.Source = new Windows.UI.Xaml.Media.Imaging.BitmapImage(new Uri("ms-appx:///SurfaceAdImages/closead.png"));
                adCloseIcon.Stretch = Stretch.Uniform;
                adCloseIcon.Height = repeateSize;
                adCloseIcon.Width = repeateSize;
                adCloseIcon.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Right;
                adCloseIcon.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Top;
                //关闭广告位事件
                adCloseIcon.Tapped += delegate(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
                {
                    try
                    {
                        if (this.popupRunningAdViewContainer != null)
                        {
                            this.popupRunningAdViewContainer.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                            this.popupRunningAdViewContainer.IsOpen = false;
                            this.popupRunningAdViewContainer = null;
                            if (this.OnAdClick != null)
                            {
                                this.OnAdClick(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.AdContent_AdPositionClosed, Description = "广告位被关闭！" });
                            }
                        }
                        this.StopAdRefreshTimer();
                        this.IsAdLoading = false;
                        this.IsAdClicking = false;
                    }
                    catch
                    {
                        LogHelper.LogInfo("广告位被关闭！", this.GetType(), "DrawAdCloseIcon");
                    }
                };
                //
                grid.Children.Add(adCloseIcon);
                return true;
            }
            catch (Exception err)
            {
                LogHelper.LogError("绘制广告关闭图标出错" + err.ToString(), this.GetType(), "DrawAdCloseIcon");
                return false;
            }
        }
        #endregion ********************广告内容图标事件********************

        #endregion ******************************广告内容******************************


        #region ******************************点击广告后的事件******************************
        void ClickAdHandler(AdResponse adContent)
        {
            switch (adContent.AdContentJumpType)
            {
                case AdJumpType.Browser:
                    this.navigatePopup = new WebViewPage(adContent);
                    this.navigatePopup.OnOpenAdContentScreenHandler += delegate(object sender, EventArgs e)
                    {
                        if (this.OnAdClick != null)
                        {
                            this.OnAdClick(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.AdContent_OpenScreen, Description = "打开广告展示窗口！" });
                        }
                    };
                    this.navigatePopup.OnCloseIconHandler += navigatePopup_OnCloseIconHandler;
                    break;
                case AdJumpType.Market:
                    MarketplaceDetailTask(new AdResponseHelper().GetJumpData(adContent));
                    break;
                case AdJumpType.Call:
                    PhoneCallTask(new AdResponseHelper().GetJumpData(adContent));
                    break;
                default:
                    break;
            }
        }

        void navigatePopup_OnCloseIconHandler(object sender, EventArgs e)
        {
            if (this.navigatePopup != null)
            {
                this.navigatePopup.OnCloseIconHandler -= navigatePopup_OnCloseIconHandler;
                this.navigatePopup.CloseWebViewPage();
                this.navigatePopup = null;
            }
            if (this.OnAdClick != null)
            {
                this.OnAdClick(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.AdContent_CloseScreen, Description = "关闭广告展示窗口！" });
            }
            //重新启动广告请求
            this.IsAdClicking = false;
            this.StartAdRefreshTimer();
        }

        /// <summary>
        /// 打开应用市场
        /// </summary>
        /// <param name="appId"></param>
        async void MarketplaceDetailTask(string appId)
        {
            try
            {
                //Uri uri = new Uri("http://www.windowsphone.com/zh-cn/store/app/iq-mission/31701cfb-1d1a-487c-bf21-bd8e7a715ebb");
                //Uri uri = new Uri(string.Concat(Constants.LaunchMarketplaceDetailTask, "31701cfb-1d1a-487c-bf21-bd8e7a715ebb"));
                Uri uri = new Uri(string.Concat(Constants.LaunchMarketplaceDetailTask, appId));
                var success = await Windows.System.Launcher.LaunchUriAsync(uri);
                if (this.OnAdClick != null)
                {
                    this.OnAdClick(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.AdContent_OpenScreen, Description = string.Concat("打开官方应用商店", success ? "成功" : "失败", "！") });
                }
                //TODO WPWRTC 打开后怎么样去重启调度器(执行了Unload事件没)？
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), "MarketplaceDetailTask");
                //
                this.IsAdClicking = false;
                this.StartAdRefreshTimer();
            }
        }

        /// <summary>
        /// 打开拔打电话启动器
        /// </summary>
        /// <param name="phoneNumber"></param>
        async void PhoneCallTask(string phoneNumber)
        {
            try
            {
                Uri uri = new Uri(string.Concat(Constants.LaunchPhoneCallTask, phoneNumber));
                var success = await Windows.System.Launcher.LaunchUriAsync(uri);
                if (this.OnAdClick != null)
                {
                    this.OnAdClick(this.LayoutRoot, new SurfaceAdEventArgs() { StatusCode = SurfaceAdStatus.AdContent_OpenScreen, Description = string.Concat("打开电话拔号器", success ? "成功" : "失败", "！") });
                }
                //TODO WPWRTC 打开后怎么样去重启调度器(执行了Unload事件没)？
            }
            catch (Exception err)
            {
                LogHelper.LogError(err.ToString(), this.GetType(), "PhoneCallTask");
                //
                this.IsAdClicking = false;
                this.StartAdRefreshTimer();
            }
        }
        #endregion ******************************点击广告后的事件******************************


    }
}
